// Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef CLOUDAPPSDK_CASSOCKET_H
#define CLOUDAPPSDK_CASSOCKET_H

#include <mutex>
#include <map>

const int SOCKET_STATUS_INIT = 0;
const int SOCKET_STATUS_RUNNING = 1;
const int SOCKET_STATUS_EXIT = -1;
const int SOCKET_STATUS_DISCONNECT = -2;

const int SOCKET_RECV_FAIL_RETRY = -1;
const int SOCKET_RECV_FAIL_DISCONNECT = -2;

const int SOCKET_SEND_FAIL_RETRY = -3;
const int SOCKET_SEND_FAIL_DISCONNECT = -4;

const int SOCKET_OPTION_BITSET_NO_DELAY = 0x1;
const int SOCKET_OPTION_BITSET_QUICK_ACK = 0x2;

class CasEventNotice {
public:
    virtual void Notice(void *tcpSocket) = 0;

    virtual ~CasEventNotice() {};
};

class CasClientNotice : public CasEventNotice {
public:
    void Notice(void *tcpSocket) override;

    ~CasClientNotice() override;
};

class CasSocket {
public:
    virtual ~CasSocket();

    virtual int Send(void *pkt, size_t size) = 0;

    virtual int Recv(void *pkt, size_t size) = 0;

    virtual void EventNotice();

    virtual void SetEventNotice(CasEventNotice *eventNotice);

    virtual void SetReconnectNotice(CasEventNotice *reconnectNotice);

    virtual CasEventNotice *GetReconnectNotice();

    virtual void SetFd(int fd);

    virtual int GetFd();

    virtual void SetStatus(int status);

    virtual int GetStatus();

    virtual int Connect()
    {
        return 0;
    }

    virtual int Reconnect()
    {
        return 0;
    }

    CasEventNotice *m_reconnectNotice = nullptr;

protected:
    int m_fd;
    int m_status;
    std::map<int, int> msg_no_map;
    std::map<int, bool> msg_valid_map;
    unsigned int m_localIp;
    unsigned int m_remoteIp;
    unsigned short int m_localPort;
    unsigned short int m_remotePort;
    unsigned int m_socketOption;
    CasEventNotice *m_eventNotice = nullptr;
    std::mutex m_socketLock;
};

#endif // CLOUDAPPSDK_CASSOCKET_H
